package cn.com.header.core.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;


/**
 * 语言相关的工具类
 * @author LinZongxue
 *
 */
public class LangUtils {
	/**
	 * 判断对象是否为空。
	 * @param obj 字符串、对象数组或java.util.Collection
	 * @return
	 */
	public static boolean isEmpty(Object obj){
		if (obj == null){
			return true;
		}
		if (obj instanceof String){
			return ((String) obj).trim().equals("");
		}
		if (obj instanceof Object[]){
			return ((Object[]) obj).length == 0;
		}
		if (obj instanceof Collection){
			return ((Collection<?>) obj).isEmpty();
		}
		return false;
	}

	/**
	 * uuid
	 * @param
	 * @return
	 */
	public static String uuidToString(){
		String str = UUID.randomUUID().toString();
		String uuidStr=str.replace("-", "");
		return uuidStr;
	}

	/**
	 * 判断对象是否为非空。
	 * @param obj 字符串、对象数组或java.util.Collection
	 */
	public static boolean isNotEmpty(Object obj){
		return !LangUtils.isEmpty(obj);
	}

	/**
	 * 比较对象，处理了null的情况，同为null时返回true。
	 */
	public static boolean equals(Object obj1, Object obj2){
		if (obj1 == null) return obj2 == null;
		return obj1.equals(obj2);
	}
	
	public static boolean notEquals(Object obj1, Object obj2){
		return !equals(obj1, obj2);
	}
	
	public static String format(String str, Object... args){
		if (str == null) return str;
		if (args.length == 0) return str;
		return String.format(str, args);
	}
	
	/**
	 * md5加密
	 */
	public static String md5(String src){
		if (src == null)
			return null;
		try{
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(src.getBytes("utf-8"));
			StringBuilder dist = new StringBuilder();
			for (byte b : md.digest()){
				String s = Integer.toHexString(0xFF & b);
				if (s.length() == 1) dist.append("0");
				dist.append(s);
			}
			return dist.toString();
		}
		catch (Exception e){
			throw new RuntimeException(e);
		}
	}
	public static String MD5Encoder(String s, String charset) {
        try {
            byte[] btInput = s.getBytes(charset);
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < md.length; i++) {
                int val = ((int) md[i]) & 0xff;
                if (val < 16){
                    sb.append("0");
                }
                sb.append(Integer.toHexString(val));
            }
            return sb.toString();
        } catch (Exception e) {
            return null;
        }
    }
	/**
	 * 去掉前后空白字符，包括中文空格
	 */
	public static String trimCn(String str){
		if (str == null)
			return null;
		str = str.trim();
		if (str.length() == 0)
			return str;
		int st = 0;
		int len = str.length();
		while((st < len) && str.charAt(st) == '　')
			st ++;
		while((st < len) && str.charAt(len - 1) == '　')
			len --;
		if (st > 0 || len < str.length())
			str = str.substring(st, len);
		return str.trim();
	}
	
	public static String nullToEmpty(String str){
		return str == null ? "" : str;
	}
	
	public static boolean contains(Object[] array, Object item){
		for (Object obj : array){
			if (equals(obj, item)){
				return true;
			}
		}
		return false;
	}

	

	



	
	/**
	 * 将字符串的前后添加'%'，并将所有空格转换为'%'，以方便进行like查询
	 */
	public static String makeSqlLike(String key){
		if (LangUtils.isEmpty(key)) return null;
		return "%" + key.trim().replaceAll("\\s", "%") + "%";
	}
	
	/**
	 * 数组中每个字符串的前后添加'%'，返回新的数组
	 */
	public static String[] makeSqlLike(String[] keys){
		if (keys == null) return null;
		String[] result = new String[keys.length];
		for(int i = 0; i < keys.length; i ++){
			result[i] = "%" + keys[i] + "%";
		}
		return result;
	}
	
	/**
	 * 将字符串按空格分隔，用数组存放，并为每个元素添加%，以便mybatis使用
	 * @param keys
	 * @return
	 */
	public static String[] makeMultiSqlLike(String keys){
		if (LangUtils.isEmpty(keys)) return null;
		List<String> result = new ArrayList<String>();
		for (String key : keys.toString().split("\\s")){
			result.add('%' + key + '%');
		}
		return result.toArray(new String[0]);
	}

	
	public static String isoToUtf8(String str){
		if (str == null) return null;
		try{
			return new String(str.getBytes("iso_8859_1"), "utf-8");
		}
		catch (Exception e){
			throw new RuntimeException(e);
		}
	}
	
	public static String utf8toIso(String str){
		if (str == null) return null;
		try{
			return new String(str.getBytes("utf-8"), "iso_8859_1");
		}
		catch (Exception e){
			throw new RuntimeException(e);
		}
	}
	
	public static String toJson(Object obj){
		if (obj == null) return null;
		try{
			return jsonMapper.writeValueAsString(obj);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	public static List<?> jsonToList(String json){
		try{
			return (List<?>)jsonMapper.readValue(json, List.class);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static Map<String, ?> jsonToMap(String json){
		try{
			return (Map<String, ?>)jsonMapper.readValue(json, Map.class);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}

	public static <T> T jsonToObject(String jsonStr, Class<T> clz){
		if (isEmpty(jsonStr)) return null;
		try{
			return jsonMapper.readValue(jsonStr, clz);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 将日期转换成字符串，格式为yyyy-MM-dd
	 */
	public static String formatDate(Date date){
		if (date == null) return null;
		return dateFmt.format(date);
	}
	/**
	 * 将日期去掉HH:mm:ss，格式为yyyy-MM-dd
	 */
	public static Date removeTime(Date date){
		if (date == null) return null;
		return LangUtils.parseDate(LangUtils.formatDate(date)); 
	}
	
	/**
	 * 将日期转换成指定格式的字符串
	 */
	public static String formatDate(Date date, String ftm){
		if (date == null) return null;
		return new SimpleDateFormat(ftm).format(date);
	}

	/**
	 * 将日期转换成字符串，格式为yyyy-MM-dd HH:mm:ss
	 */
	public static String formatDateTime(Date date){
		if (date == null) return null;
		return datetimeFmt.format(date);
	}
	
	public static String formatTime(Date date){
		if (date == null) return null;
		return timeFmt.format(date);
	}
	
	/**
	 * 格式化时间长度，返回格式：xx天xx小时xx分ss秒
	 * @param timePeriod 时间长度，单位为毫秒
	 * @return
	 */
	public static String formatTimePeriod(long timePeriod){
		timePeriod /= 1000;
		if (timePeriod <= 0) return "0秒";
		long days = timePeriod / 86400;
		long hours = timePeriod % 86400 / 3600;
		long mins = timePeriod % 3600 / 60;
		long secs = timePeriod % 60;
		String timeStr = "";
		if (days > 0) timeStr += days + "天";
		if (hours > 0) timeStr += hours + "小时";
		if (mins > 0) timeStr += mins + "分";
		if (secs > 0) timeStr += secs + "秒";
		return timeStr;
	}
	
	/**
	 * 格式化时间长度，返回相差多少天
	 * @param timePeriod 时间长度，单位为毫秒
	 * @return
	 */
	public static String formatDays(long timePeriod){
		timePeriod /= 1000;
		if (timePeriod <= 0) return "-1";
		long days = timePeriod / 86400;
		String timeStr = "0";
		if (days > 0) timeStr = days+"";
		return timeStr;
	}
	
	/**
	 * 将日期字符串转换成日期，只支持如下格式：<br/>
	 * yyyy-M[M]-d[d]、yyyy-M[M]-d[d] H[H]:m[m] 或 yyyy-M[M]-d[d] H[H]:m[m]:s[s] <br/>
	 * 如果转换转换出错返回null
	 */
	public static Date parseDate(String str) {
		if (LangUtils.isEmpty(str))
			return null;
		str = str.trim();
		String fmt = null;
		if (StringUtils.isNumeric(str)) {
			if (str.length() == 8)
				fmt = "yyyyMMdd";
			else {
				Long mills = LangUtils.parseLong(str);
				if (mills != null)
					return new Date(mills);
			}
		} else {
			if (str.contains("T")) {
				str = str.replace("T", " "); // html5的datetime-local控件以T来分隔日期和时间
			}

			if (StringUtils.countMatches(str, "-") == 1) { // 年月
				fmt = (str.length() == 7) ? "yyyy-MM" : "yyyy-M";
			} else if (str.length() == 10)
				fmt = "yyyy-MM-dd";
			else if (str.length() == 16)
				fmt = "yyyy-MM-dd HH:mm";
			else if (str.length() == 19)
				fmt = "yyyy-MM-dd HH:mm:ss";
			else if (str.indexOf(' ') == -1)
				fmt = "yyyy-M-d";
			else if (str.indexOf(':') == str.lastIndexOf(':'))
				fmt = "yyyy-M-d H:m";
			else
				fmt = "yyyy-M-d H:m:s";
		}

		if (fmt != null) {
			try {
				return new SimpleDateFormat(fmt).parse(str);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * 将字符串转换为Long，转换失败返回null
	 */
	public static Long parseLong(String str){
		return LangUtils.parseLong(str, null);
	}
	
	/**
	 * 将字符串转换为Long，转换失败返回defaultValue
	 */
	public static Long parseLong(String str, Long defaultValue){
		if (str == null) return null;
		try{
			return Long.parseLong(str);
		}
		catch(Exception e){
			
		}
		return defaultValue;
	}
	
	/**
	 * 将字符串转换为Integer，转换失败返回null
	 */
	public static Integer parseInt(String str){
		return LangUtils.parseInt(str, null);
	}
	
	/**
	 * 将字符串转换为Integer，转换失败返回defaultValue
	 */
	public static Integer parseInt(String str, Integer defaultValue){
		if (str == null) return null;
		try{
			return Integer.parseInt(str);
		}
		catch(Exception e){
			
		}
		return defaultValue;
	}
	
	/**
	* 将字符串转换为Float，转换失败返回null
	*/
	public static Float parseFloat(String str){
		return LangUtils.parseFloat(str, null);
	}
	
	/**
	 * 将字符串转换为Float，转换失败返回defaultValue
	 */
	@SuppressWarnings("all")
	public static float parseFloat(String str, Float defaultValue){
		if (str == null) return (Float) null;
		try{
			return Float.parseFloat(str);
		}
		catch(Exception e){
			
		}
		return defaultValue;
	}


	
	/**
	 * 将用下划线或减号分隔的单词改成java的驼峰命名风格
	 */
	public static String toJavaName(String str){
		if (str == null) return null;
		str = str.toLowerCase();
		StringBuilder javaName = new StringBuilder();
		boolean upper = false;
		for (int i = 0; i < str.length(); i ++){
			char c = str.charAt(i);
			if (c == '_' || c == '-'){
				upper = true;
			}
			else{
				javaName.append(upper ? Character.toUpperCase(c) : c);
				upper = false;
			}
		}
		return javaName.toString();
	}
	
	/**
	 * 将java的驼峰命名风格的单词修改成将带下划线的风格
	 */
	public static String toUnlineName(String javaName){
		if (javaName == null) return null;
		javaName = javaName.trim();
		StringBuilder unlineName = new StringBuilder();
		for (int i = 0; i < javaName.length(); i ++){
			char c = javaName.charAt(i);
			if (Character.isUpperCase(c)){
				unlineName.append("_").append(Character.toLowerCase(c));
			}
			else{
				unlineName.append(c);
			}
		}
		return unlineName.toString();
	}
	
	public static String clearHtmlTag(String html){
		if (html == null) return null;
		return html.replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "");
	}

	
	/**
	 * Thread.sleep(ms);
	 */
	public static void sleep(long ms){
		try{
			Thread.sleep(ms);
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private static SimpleDateFormat datetimeFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");
	private static SimpleDateFormat timeFmt = new SimpleDateFormat("HH:mm:ss");
	
	private static ObjectMapper jsonMapper = new ObjectMapper();
	static {
		jsonMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
	}

	

}
